﻿using Base.FileCollect;
using Base.FileGateway.PdfConvert.Model;
using Base.FileModel.DB;
using Base.FileModel.UserFile;
using Base.FileModel.UserFileDir;
using Base.FileRemoteModel;
using Base.FileService.Helper;
using Base.FileService.Interface;
using Base.FileService.Model;
using WeDonekRpc.Client;
using WeDonekRpc.Client.Interface;
using WeDonekRpc.Helper;
namespace Base.FileGateway.PdfConvert
{
    internal class UserPdfTask
    {
        private PdfArg _Arg;

        private volatile int _Status = 0;
        private string _error;
        private UserFile _File;
        public UserPdfTask ( string taskId )
        {
            this.TaskId = taskId;
        }
        public string TaskId
        {
            get;
        }
        public bool IsComplete => this._Status != 0;

        public int EndTime
        {
            get;
            private set;
        }
        public void BeginTask ( PdfArg arg )
        {
            this._Arg = arg;
            _ = Task.Factory.StartNew(this._ExecTask);
        }
        private UserFileDto _UserFile;
        private void _ExecTask ()
        {
            using ( IScoreService scope = RpcClient.Ioc.CreateTempScore() )
            {
                IUserFileCollect userFile = scope.Resolve<IUserFileCollect>();
                IPdfFileConfig config = scope.Resolve<IPdfFileConfig>();
                try
                {
                    this._UserFile = userFile.GetFile(this._Arg.FileId);
                    if ( !config.AllowExtension.Contains(this._UserFile.Extension) )
                    {
                        this._SetError("file.type.not.allow.convert");
                        return;
                    }
                    FileInfo file = new FileInfo(this._UserFile.FilePath);
                    if ( !file.Exists )
                    {
                        this._SetError("file.not.find");
                        return;
                    }
                    PdfConvertTask res = FilePdfService.CreateTask(this._UserFile.FileId, file);
                    res.RegEvent(this._Complete);
                }
                catch ( Exception e )
                {
                    this._SetError(e);
                }
            }
        }

        private void _Complete ( PdfResult result )
        {
            if ( result.IsError )
            {
                this._SetError(result.Error);
            }
            else
            {
                using ( IScoreService scope = RpcClient.Ioc.CreateTempScore() )
                {
                    IUserFileDirCollect userDir = scope.Resolve<IUserFileDirCollect>();
                    IUserFileCollect userFile = scope.Resolve<IUserFileCollect>();
                    IFileConfig config = scope.Resolve<IFileConfig>();
                    UserFileDirDto dir = userDir.GetDir(this._Arg.DirKey);
                    UserFileAdd add = new UserFileAdd
                    {
                        UserId = this._Arg.UserId,
                        UserType = this._Arg.UserType,
                        UserDirId = dir.Id,
                        Power = dir.Power,
                        PowerCode = dir.ReadPower,
                        LinkBizPk = this._Arg.LinkBizPk,
                        Tag = this._Arg.Tag,
                        Extension = ".pdf",
                        OperatePower = dir.UpPower,
                        FileName = Path.GetFileNameWithoutExtension(this._UserFile.FileName) + ".pdf",
                        FileType = FileType.doc,
                        FileId = result.FileId,
                    };
                    DBUserFileList res;
                    try
                    {
                        res = userFile.Add(add);
                    }
                    catch ( Exception e )
                    {
                        this._SetError(e);
                        return;
                    }
                    this._File = new UserFile
                    {
                        FileId = res.Id,
                        FileName = add.FileName,
                        FileUri = res.GetFileUri(config),
                    };
                    this.EndTime = HeartbeatTimeHelper.HeartbeatTime;
                    this._Status = 1;
                }
            }
        }

        private void _SetError ( string error )
        {
            this._error = error;
            this.EndTime = HeartbeatTimeHelper.HeartbeatTime;
            this._Status = 2;
        }
        private void _SetError ( Exception e )
        {
            ErrorException error = ErrorException.FormatError(e);
            if ( error.IsSystemError )
            {
                error.Save("file");
            }
            this._error = error.ErrorCode;
            this.EndTime = HeartbeatTimeHelper.HeartbeatTime;
            this._Status = 2;
        }
        public PdfCovertRes GetResult ()
        {
            if ( this._Status == 2 )
            {
                throw new ErrorException(this._error);
            }
            return new PdfCovertRes
            {
                TaskId = this.TaskId,
                IsComplete = this._Status == 1,
                File = this._File
            };
        }
    }
}
